<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */

namespace app\service\notice\qywx;

use app\enum\NoticeEnum;
use app\enum\QywxUrlEnum;
use app\service\BaseService;
use app\service\notice\NoticeInterface;
use app\service\notice\NoticeLogTrait;
use proxy\Client;
use think\Exception;

final class QywxWebHookService extends BaseService implements NoticeInterface
{
    use NoticeLogTrait;

    /**
     * @var string 企业id
     */
    private const CORPID = 'wwe5e95925d980930f';

    /**
     * @var string 应用密钥
     */
    private const SECRET = 'iR-_Gwd9cKNXNpMANmr3Df6IXOSeRKlSfgRTfi2jKD4';

    /**
     * @var array 请求参数
     */
    protected array $req = [];

    /**
     * @var array 应答参数
     */
    protected array $rep = [];

    /**
     * @var array 接收人
     */
    protected array $staffs = [];

    /**
     * @var int 通知类型
     */
    protected int $noticeType = NoticeEnum::NOTICE_TYPE_QYWX;

    /**
     * @var array 配置
     */
    private array $conf = [];

    /**
     * @var string token
     */
    private string $token = '';

    public function __construct(array $conf = [])
    {
        $this->setConf($conf);
    }

    /**
     * 添加公共参数.
     * @param array $params 请求参数
     */
    public function getParam(array $params = []): array
    {
        return [
            'msgtype' => 'markdown',
            'markdown' => [
                'content' => $params['send_date'] . "\n" .
                    "[{$params['title']}]({$params['messageUrl']})",
            ],
        ];
    }

    /**
     * 设置配置.
     * @param array $conf 配置
     * @return bool
     */
    public function setConf(array $conf = []): bool
    {
        $this->conf = $conf;
        return true;
    }

    /**
     * 发送单个消息.
     * @param array $params 请求参数
     * @return true
     * @throws Exception
     */
    public function sendSingleMessage(array $params = []): bool
    {
        $this->req = $this->getParam($params);
        // 验签
        $timestamp = time();
        $stringToSign = $timestamp . "\n" . self::SECRET . "\n" . json_encode($this->req);
        $sign = urlencode(base64_encode(hash_hmac('sha256', $stringToSign, self::SECRET, true)));
        $newHeaders = self::getHeader();
        $client = new Client();
        $newServiceName = QywxUrlEnum::getServiceName('qywx');
        $serviceUrl = $this->conf['link'] ?? '';
        if (! $serviceUrl) {
            return self::setError('未知webhook');
        }
        $serviceUrl .= '&amp;timestamp=' . $timestamp . '&amp;sign=' . $sign;
        $this->rep = $client->postJson($newServiceName, $serviceUrl, $this->req)->setHeader($newHeaders)->exec(Client::RETURN_TYPE);
        if (! $this->setNoticeLog()) {
            return false;
        }
        return $this->isSendSuccess() || self::setError($res['msg'] ?? '发送失败');
    }

    /**
     * 是否发送成功.
     * @return bool
     */
    public function isSendSuccess(): bool
    {
        return isset($this->rep['errcode']) && $this->rep['errcode'] == 0;
    }

    /**
     * 发送批量消息.
     * @param array $params 请求参数
     * @return bool
     */
    public function sendBatchMessage(array $params = []): bool
    {
        // todo 实现企业微信webhook批量发送
        return true;
    }

    /**
     * 设置header.
     * @return string[]
     */
    private function getHeader(): array
    {
        return [
            'Authorization' => 'Bearer ' . $this->token,
            'Content-Type' => 'application/json; charset=utf-8',
        ];
    }
}
